<template>
  <div class="main">
    <div class="bg" ref="ref_bg">
      <template v-for="(item, index) in state.arr">
        <div class="item __hover" ref="ref_items">
          <div class="item-content">
            <span>{{item}}</span>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>

<script setup lang="ts">
import {getCurrentInstance, onMounted, reactive, ref} from "vue";
import {gsap} from 'gsap'
const {proxy} = getCurrentInstance()
const state: any = reactive({
  arr: 50,
  itemWidth: 0,
  itemHeight: 0,
  bgWidth: 0,
  bgHeight: 0,
  isMove: false,
  mouseX: 0,
  mouseY: 0,
  arrData: [],
  scale: 0
})
const ref_items = ref()
const ref_bg = ref()
const resize = () => {
  state.bgWidth = ref_bg.value.clientWidth
  state.bgHeight = ref_bg.value.clientHeight
  state.itemWidth = ref_items.value[0].clientWidth
  state.itemHeight = ref_items.value[0].clientHeight
  state.scale = document.body.offsetWidth / state.bgWidth;
  ref_bg.value.style.transform = `scale(${state.scale})`;
  gsap.to(ref_items.value, {
    transform: `translate(0,0)`,
    duration: 0,
    ease: 'power4.out'
  });
  state.arrData = []
  ref_items.value.forEach(v => {
    state.arrData.push({
      node: v,
      x: v.offsetLeft,
      y: v.offsetTop,
      offsetX: 0,
      offsetY: 0,
      ani: 0
    })
  })
}
const move = (x, y) => {
  if (!state.isMove) {
    return
  }
  const offsetX = (x - state.mouseX) / state.scale
  const offsetY = (y - state.mouseY) / state.scale
  state.arrData.forEach((v) => {
    v.offsetX += offsetX;
    let duration = 1
    if (v.x + v.offsetX > state.bgWidth) {
      v.offsetX -= state.bgWidth
      duration = 0
    }
    if (v.x + v.offsetX < -state.itemWidth) {
      v.offsetX += state.bgWidth;
      duration = 0
    }
    v.offsetY += offsetY;
    if (v.y + v.offsetY > state.bgHeight) {
      v.offsetY -= state.bgHeight
      duration = 0
    }
    if (v.y + v.offsetY < -state.itemHeight) {
      v.offsetY += state.bgHeight;
      duration = 0
    }
    // v.node.style.transform = `translate(${v.offsetX}px, ${v.offsetY}px)`
    if (v.ani) v.ani.kill();
    v.ani = gsap.to(v.node, {
      transform: `translate(${v.offsetX}px,${v.offsetY}px)`,
      duration: duration,
      ease: 'power4.out'
    });
  });
  state.mouseX = x
  state.mouseY = y
}
onMounted(() => {
  resize()
  window.addEventListener("resize", () => {
      resize();
  })
  ref_bg.value.addEventListener("mousedown", (e) => {
    state.isMove = true
    state.mouseX = e.clientX
    state.mouseY = e.clientY
  });
  ref_bg.value.addEventListener("mouseup", () => {
    state.isMove = false
  });
  ref_bg.value.addEventListener("mouseleave", () => {
    state.isMove = false
  });
  ref_bg.value.addEventListener("mousemove", (e) => {
    move(e.clientX, e.clientY);
  });
})
</script>

<style lang="scss" scoped>
.main {
  width: 100%;
  height: 100%;
  background-color: #000000;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  .bg {
    position: absolute;
    display: grid;
    grid-template-columns: repeat(10, 1fr);
    .item {
      margin-right: 100em;
      margin-bottom: 100em;
      border: 1px solid #FFFFFF;
      width: 1000em;
      height: 1400em;
      font-size: 1px;
      background-color: #f1b4b4;
      color: #000000;
      .item-content {
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        &:hover {
          transform: scale(2);
        }
        >span {
          font-size: 100px;
        }
      }
    }
  }
}
@media screen and (max-aspect-ratio: 1.5/1) {
  .item, .block {
    font-size: 2px;
  }
}

@media screen and (max-aspect-ratio: 0.8/1) {
  .item, .block {
    font-size: 2.8px;
  }
}
</style>
